package com.dhcc.utils;

import com.dhcc.entity.SysDepartment;
import com.dhcc.vo.SysDepartmentTree;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class DepartmentTreeBuilder {
    /**
     * 构建部门树
     *
     * @param allDepts 所有部门列表（原始 SysDept 列表）
     * @param parentId 父部门 ID，根部门为 null
     * @return 部门树
     */
    public static List<SysDepartmentTree> buildDeptTree(List<SysDepartment> allDepts, String parentId) {
        // 将 SysDept 转换为 SysDeptVO
        List<SysDepartmentTree> allDeptVOs = convertToDeptVOList(allDepts);

        // 使用转换后的 VO 列表递归构建树
        return buildTreeFromVO(allDeptVOs, parentId);
    }

    /**
     * 将 List<SysDept> 转换为 List<SysDeptVO>
     *
     * @param allDepts 原始部门列表
     * @return 转换后的部门 VO 列表
     */
    private static List<SysDepartmentTree> convertToDeptVOList(List<SysDepartment> allDepts) {
        List<SysDepartmentTree> voList = new ArrayList<>();
        for (SysDepartment dept : allDepts) {
            voList.add(convertToVO(dept));
        }
        return voList;
    }

    /**
     * 构建部门树（直接操作 SysDeptVO 列表）
     *
     * @param allDepts 所有部门 VO 列表
     * @param parentId 父部门 ID，根部门为 null
     * @return 部门树
     */
    public static List<SysDepartmentTree> buildTreeFromVO(List<SysDepartmentTree> allDepts, String parentId) {
        List<SysDepartmentTree> tree = new ArrayList<>();
        for (SysDepartmentTree dept : allDepts) {
            // 判断当前部门是否属于指定父部门
            if (Objects.equals(dept.getParementId(), parentId)) {
                // 递归设置子部门
                dept.setChildren(buildTreeFromVO(allDepts, dept.getDepartmentId()));
                tree.add(dept);
            }
        }
        return tree;
    }

    /**
     * 将 SysDept 转换为 SysDeptVO
     *
     * @param dept SysDept 实体
     * @return SysDeptVO 对象
     */
    public static SysDepartmentTree convertToVO(SysDepartment dept) {
        SysDepartmentTree vo = new SysDepartmentTree();
        BeanUtils.copyProperties(dept, vo);
        return vo;
    }
}
